/**
 *    Copyright (c) [2022] [中和农信]
 *    rabbit-mq-plus is licensed under Mulan PSL v2.
 *    You can use this software according to the terms and conditions of the Mulan PSL v2.
 *    You may obtain a copy of Mulan PSL v2 at:
 *             http://license.coscl.org.cn/MulanPSL2
 *    THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 *    See the Mulan PSL v2 for more details.
 *
 */
package com.cfpamf.athean.rabbit.mq.plus.consumer.core.impl;

import java.io.IOException;

import javax.annotation.Resource;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import com.cfpamf.athean.rabbit.mq.plus.common.exception.RabbitMqPlusException;
import com.cfpamf.athean.rabbit.mq.plus.common.utils.RabbitMqUtils;
import com.cfpamf.athean.rabbit.mq.plus.consumer.core.RabbitMqPlusConsumer;
import com.cfpamf.athean.rabbit.mq.plus.domain.dto.RabbitMqPlusConsumerDTO;
import com.cfpamf.athean.rabbit.mq.plus.service.RabbitMqPlusConsumerTaskService;
import com.cfpamf.athean.rabbit.mq.plus.validation.RabbitMqPlusConsumerValidation;
import com.cfpamf.athena.utils.StringUtils;
import com.cfpamf.athena.utils.Tools;
import com.rabbitmq.client.Channel;

import lombok.extern.slf4j.Slf4j;

/**
 * 类DefaultRabbitMqPlusConsumer.java的实现描述：
 *
 * @author Andy（陈洪桥）2022年11月25 15:06
 */
@Slf4j
@Component("rabbitMqPlusConsumer")
public class DefaultRabbitMqPlusConsumer implements RabbitMqPlusConsumer {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private RabbitMqPlusConsumerHandler rabbitMqPlusConsumerHandler;

    @Resource
    private RabbitMqPlusConsumerTaskService rabbitMqPlusConsumerTaskService;

    /**
     * 启用消费者监听
     * 
     * @param consumerDTO
     * @throws RabbitMqPlusException
     */
    @Override
    public void runConsumeListener(final RabbitMqPlusConsumerDTO consumerDTO) throws RabbitMqPlusException {
        try {
            RabbitMqPlusConsumerValidation.runConsumeListenerValidation(consumerDTO);
            log.info("[rabbitMqPlus]启用业务消息消费者队列关系绑定:{}", consumerDTO.getQueueName());
            this.runRabbitMqPlusBusinessMessageConsumeListener(consumerDTO);
        } catch (Exception e) {
            throw new RabbitMqPlusException(String.format("[rabbitMqPlus]消费者，业务消息消费失败异常，exchange：%s queueName：%s",
                consumerDTO.getQueueName(), consumerDTO.getExchangeName()), e);
        }
    }

    /**
     * 运行业务消息消费者队列监听
     * 
     * @param consumerDTO
     * @throws IOException
     */
    private void runRabbitMqPlusBusinessMessageConsumeListener(final RabbitMqPlusConsumerDTO consumerDTO)
        throws IOException {
        // 业务队列交换机绑定成功
        RabbitMqUtils.queueBindexchange(consumerDTO.getQueueName(), consumerDTO.getExchangeName());
        log.info("[rabbitMqPlus]启用业务消息消费者队列关系绑定:{}", consumerDTO.getQueueName());
        // 创建信道
        final Channel channel = rabbitTemplate.getConnectionFactory().createConnection().createChannel(Boolean.FALSE);
        channel.basicConsume(consumerDTO.getQueueName(), Boolean.FALSE,
            Tools.isEmpty(consumerDTO.getConsumerTag()) ? StringUtils.EMPTY : consumerDTO.getConsumerTag(),
            new RabbitMqPlusBusinessMessageConsumeListener(rabbitMqPlusConsumerHandler, rabbitMqPlusConsumerTaskService,
                consumerDTO, channel));
        log.info("[rabbitMqPlus]业务消息消费者队列监听:{} running", consumerDTO.getQueueName());
    }

}
